package com.hoan.bitmap;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;


import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class BitmapMainActivity extends Activity {
    private static final String TAG = "BitmapMainActivity";

    private long mPreTime;

    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap_main);

        initView();
    }

    public static Object getUnsafeObject() {
        Class clazz = AtomicInteger.class;
        try {
            // Reflective access to U will throw an exception when targeting API 29 and above
            //针对API 29及以上版本时，对U的反射访问将引发异常
            Field uFiled = clazz.getDeclaredField("U");
            uFiled.setAccessible(true);
            return uFiled.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static long getVariableOffset(Object target, String variableName) {
        Object unsafeObject = getUnsafeObject();
        if (unsafeObject != null) {
            try {
                Method method = unsafeObject.getClass().getDeclaredMethod("objectFieldOffset", Field.class);
                method.setAccessible(true);
                Field targetFiled = target.getClass().getDeclaredField(variableName);
                return (long) method.invoke(unsafeObject, targetFiled);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    public static void printObjectOffsets(Object target) {
        Class targetClass = target.getClass();
        Field[] fields = targetClass.getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            Log.d("offset", name + " offset: " + getVariableOffset(target, name));
        }
    }

    public void initView() {
        TextView tv_normal = findViewById(R.id.tv_normal);
        tv_normal.setOnClickListener(v -> startActivity(new Intent(BitmapMainActivity.this, BitmapNormalActivity.class)));

        XXPermissions.with(this)
                // 申请单个权限
                .permission(Permission.ACCESS_FINE_LOCATION)
                // 申请多个权限
                .permission(Permission.Group.STORAGE)
                // 设置权限请求拦截器（局部设置）
                //.interceptor(new PermissionInterceptor())
                // 设置不触发错误检测机制（局部设置）
                //.unchecked()
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all) {
//                            Toast.makeText(BitmapMainActivity.this, "获取权限成功", Toast.LENGTH_SHORT).show();
                        } else {
                            Toast.makeText(BitmapMainActivity.this, "获取部分权限成功，但部分权限未正常授予", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        if (never) {
                            Toast.makeText(BitmapMainActivity.this, "被永久拒绝授权，请手动授予权限", Toast.LENGTH_SHORT).show();
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            XXPermissions.startPermissionActivity(BitmapMainActivity.this, permissions);
                        } else {
                            Toast.makeText(BitmapMainActivity.this, "获取权限失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });


        Log.d(TAG, "------start print fruit offset!------");
//        printObjectOffsets(new Fruit());

        Log.d(TAG, "------start print apple offset!------");
//        printObjectOffsets(new Apple());

        // 输出结果 （Android 8.0模拟器）
        /**
         *
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/BitmapMainActivity: ------start print fruit offset!------
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap W/com.hoan.bitma: Accessing hidden field Ljava/util/concurrent/atomic/AtomicInteger;->U:Lsun/misc/Unsafe; (greylist-max-o, reflection, allowed)
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/offset: size offset: 8
         *
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/BitmapMainActivity: ------start print apple offset!------
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/offset: brother offset: 12
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/offset: color offset: 20
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/offset: create_time offset: 24
         * 2022-08-01 14:28:15.324 26477-26477/com.hoan.bitmap D/offset: name offset: 16
         *
         */
    }

    @Override
    public void onBackPressed() {
        if (System.currentTimeMillis() - mPreTime > 2000) { //两次点击间隔大于2秒
            Toast.makeText(this, "再按一次，退出应用", Toast.LENGTH_SHORT).show();
            mPreTime = System.currentTimeMillis();
            return;
        } else {
            finish();
        }
        super.onBackPressed();// finish()
    }
}